본문으로 건너뛰기

#1. 함수형 프로그래밍이란 무엇인가?

함수형 프로그래밍이란?

함수형 프로그래밍이란 순수 함수로만 이루어진 프로그램을 말하며, **부수효과(side effect)**가 없는 방식으로 개발하는 것이다.

부수효과의 예

  • 외부 변수를 수정
  • 자료구조를 제자리에서 수정
  • 객체 필드 변경
  • 예외 발생, 오류 출력
  • 콘솔 출력, 사용자 입력
  • 파일 입출력
  • 화면 그리기

→ 이런 부수효과를 제거함으로써 모듈성, 재사용성, 테스트 편의성, 병렬화, 분석 가능성을 높일 수 있다.


1.1 FP의 이점: 간단한 예제

class Cafe {
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
cc.charge(cup.price)
cup
}
}
  • cc.charge()는 부수효과를 포함 (거래, 청구 등 외부 상태 변화)
  • 테스트가 어려움
  • 재사용 불편

개선 예시

class Cafe {
def buyCoffee(cc: CreditCard, p: Payments): Coffee = {
val cup = new Coffee()
p.charge(cc, cup.price)
cup
}
}
  • Payments를 외부에서 주입
  • Mock 가능
  • 테스트 편리

함수형 방식으로 개선

class Cafe {
def buyCoffee(cc: CreditCard): (Coffee, Charge) = {
val cup = new Coffee()
(cup, Charge(cc, cup.price))
}
}

case class Charge(cc: CreditCard, amount: Double) {
def combine(other: Charge): Charge = {
if (cc == other.cc)
Charge(cc, amount + other.amount)
else
throw new Exception("다른 카드의 청구서는 합칠 수 없습니다.")
}
}
  • Charge를 반환 → 결제는 외부에서
  • 청구 정보가 명시적 값으로 처리됨
  • 테스트, 재사용, 일반화 모두 용이

여러 건 구매

def buyCoffees(cc: CreditCard, count: Int): (List[Coffee], Charge) = {
val purchases = List.fill(count)(buyCoffee(cc))
val (coffees, charges) = purchases.unzip
(coffees, charges.reduce(_.combine(_)))
}

1.2 순수 함수란?

  • 입력 A → 출력 B 를 항상 동일하게 반환
  • 외부 상태에 의존하지 않음
  • 계산 이외의 작업을 하지 않음

1.3 참조 투명성과 치환 모형

참조 투명성

  • 같은 입력 → 항상 같은 출력
  • 표현식을 동일한 값으로 치환 가능
  • 예:
def buyCoffee(cc: CreditCard): Coffee = {
val cup = new Coffee()
cc.charge(cup.price)
cup
}

// 비순수: new Coffee() ≠ buyCoffee(cc)

치환 모형

  • 프로그램이 수행하는 모든 것이 반환 값으로 대표됨
  • → 추론이 쉬움, 디버깅이 쉬움

1.4 요약

  • 함수형 프로그래밍은 부수효과 제거를 통해 모듈성과 예측 가능성을 확보
  • 순수함수와 참조 투명성은 프로그램을 안전하고 단순하게 만듦
  • 치환 가능한 코드 구조는 테스트와 분석을 쉽게 해줌